package voloshyn.paliy.camera;

import java.io.ByteArrayOutputStream;

import android.app.Activity;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;

import com.testtest.testcameraproject.R;

public class CameraActivity extends Activity implements SurfaceHolder.Callback {
	// private static final int CAMERA_WIDHT=320;
	// private static final int CAMERA_HEIGHT=240;
	private static final int CAMERA_WIDHT = 176;
	private static final int CAMERA_HEIGHT = 144;
	private static String TAG = CameraActivity.class.getName();

	private BluetoothCameraSocket connectCameraSocket;
	private SurfaceView surface;
	private SurfaceHolder surfaceHolder;
	private Camera camera;
	private boolean cameraConfigured = false;
	private boolean inPreview;

	private long time;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		setContentView(R.layout.camera_activity);
		createSurfaceView();
	}

	@Override
	protected void onResume() {
		initializeCamera();
		startPreview();
		listenForConnection();
		super.onResume();
	}

	public void createSurfaceView() {
		float widht = getResources().getDisplayMetrics().widthPixels;
		float height = getResources().getDisplayMetrics().heightPixels;

		float maxWidth = CAMERA_WIDHT;
		float maxHeight = CAMERA_HEIGHT;

		float widthRatio = maxWidth / widht;
		float heightRatio = maxHeight / height;

		float maxRatio = Math.max(widthRatio, heightRatio);

		int surfaceWidth = (int) (maxWidth / maxRatio);
		int surfaceHeight = (int) (maxHeight / maxRatio);

		surface = new SurfaceView(this);
		LinearLayout baseLayout = (LinearLayout) findViewById(R.id.camera_view);

		surface.setLayoutParams(new ViewGroup.LayoutParams(surfaceWidth,
				surfaceHeight));
		baseLayout.addView(surface);
	}

	@Override
	protected void onPause() {
	    super.onPause();
		if (inPreview) {
			camera.stopPreview();
		}
		camera.release();
		camera = null;
		inPreview = false;
		connectCameraSocket.disconnect();
		
	}

	private void initializeCamera() {
		surfaceHolder = surface.getHolder();
		surfaceHolder.addCallback(this);
		camera = Camera.open();

		camera.setPreviewCallback(new PreviewCallback() {

			@Override
			public void onPreviewFrame(byte[] data, Camera camera) {
				// if(time>0)
				// {
				// Log.v(TAG,
				// "[onPreviewFrame] time:"+(System.currentTimeMillis()-time));
				// }
				// time=System.currentTimeMillis();
				YuvImage image = new YuvImage(data, ImageFormat.NV21,
						CAMERA_WIDHT, CAMERA_HEIGHT, null);
				Rect rectangle = new Rect();
				rectangle.bottom = CAMERA_HEIGHT;
				rectangle.top = 0;
				rectangle.left = 0;
				rectangle.right = CAMERA_WIDHT;
				ByteArrayOutputStream out2 = new ByteArrayOutputStream();
				image.compressToJpeg(rectangle, 100, out2);
				byte[] imageArray = out2.toByteArray();
				byte[] lengthArray = MathUtils.my_int_to_bb_le(imageArray.length);
				byte[] resultArray = new byte[imageArray.length + lengthArray.length];
				System.arraycopy(lengthArray, 0, resultArray, 0, lengthArray.length);
				System.arraycopy(imageArray, 0, resultArray, lengthArray.length, imageArray.length);
				connectCameraSocket.sendFrame(resultArray);
			}
		});
	}

	private void listenForConnection() {
		if (connectCameraSocket != null) {
			return;
		}
		connectCameraSocket = new BluetoothCameraSocket();
		connectCameraSocket.setOnConnectListener(new OnConnectListener() {
			@Override
			public void inputData(String theData) {
			}

			@Override
			public void disconnectedError() {
				connectCameraSocket = null;
				listenForConnection();
			}

			@Override
			public void disconnected() {
				connectCameraSocket = null;
			}
		});
		connectCameraSocket.start();
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		initPreview(width, height);
		startPreview();
	}

	private void startPreview() {
		if (cameraConfigured && camera != null) {
			camera.startPreview();
			inPreview = true;
		}
	}

	private void initPreview(int width, int height) {
		if (camera != null && surfaceHolder.getSurface() != null) {
			try {
				camera.setPreviewDisplay(surfaceHolder);
			} catch (Throwable t) {
				t.printStackTrace();
			}
			if (!cameraConfigured) {
				Camera.Parameters parameters = camera.getParameters();
//				parameters.setPreviewFpsRange(60, 60);
				// parameters.setPreviewFormat(pixel_format)
				// parameters.setPreviewFormat(ImageFormat.YUY2);
				parameters.setPreviewSize(CAMERA_WIDHT, CAMERA_HEIGHT);
				camera.setParameters(parameters);
				cameraConfigured = true;

			}
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
	}
}